/**
 * Copyright (C) 2012 The SkyTvOS Project
 * <p/>
 * Version     Date           Author
 * ─────────────────────────────────────
 * 2014-6-25         luwei
 */

package com.coocaa.x.framework.utils;

import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.Bitmap.Config;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.ColorMatrix;
import android.graphics.ColorMatrixColorFilter;
import android.graphics.LinearGradient;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.PaintFlagsDrawFilter;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffXfermode;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.Shader;
import android.graphics.drawable.AnimationDrawable;
import android.graphics.drawable.BitmapDrawable;

import java.util.ArrayList;
import java.util.List;

public class ImageUtils {
    public static class CustomAnimationDrawable extends AnimationDrawable {

        private int mNumber = 0;

        public interface AnimationDrawableListener {
            public void onAnimationEnd();
        }

        private AnimationDrawableListener mAnimListener = null;

        public void setAnimationDrawableListener(AnimationDrawableListener listener) {
            this.mAnimListener = listener;
        }

        @Override
        public void draw(Canvas canvas) {
            super.draw(canvas);
            mNumber++;
            if (mNumber >= getNumberOfFrames() - 1) {
                if (mAnimListener != null) {
                    mAnimListener.onAnimationEnd();
                }
            }
        }

        @Override
        public void start() {
            mNumber = 0;
            super.start();
        }

    }

    public static List<ImagePiece> split(Bitmap bitmap, int xPiece, int yPiece) {

        List<ImagePiece> pieces = new ArrayList<ImagePiece>(xPiece * yPiece);
        int width = bitmap.getWidth();
        int height = bitmap.getHeight();
        int pieceWidth = width / xPiece;
        int pieceHeight = height / yPiece;
        for (int i = 0; i < yPiece; i++) {
            for (int j = 0; j < xPiece; j++) {
                ImagePiece piece = new ImagePiece();
                piece.index = j + i * xPiece;
                int xValue = j * pieceWidth;
                int yValue = i * pieceHeight;
                piece.bitmap = Bitmap.createBitmap(bitmap, xValue, yValue, pieceWidth, pieceHeight);
                pieces.add(piece);
            }
        }
        return pieces;
    }

    public static CustomAnimationDrawable generateAnimation(Bitmap bitmap, int xPiece, int yPiece) {
        return generateAnimation(split(bitmap, xPiece, yPiece));
    }

    public static CustomAnimationDrawable generateAnimation(List<ImagePiece> pieces) {
        CustomAnimationDrawable drawable = new CustomAnimationDrawable();
        for (ImagePiece piece : pieces) {
            drawable.addFrame(new BitmapDrawable(piece.bitmap), 30);
        }
        return drawable;
    }

    public static class ImagePiece {
        public int index = 0;
        public Bitmap bitmap = null;
    }

    public static Bitmap decodeSampledBitmapFromResource(Resources res, int resId, int reqWidth,
                                                         int reqHeight) {

        // First decode with inJustDecodeBounds=true to check dimensions
        // TypedValue value = new TypedValue();
        // res.openRawResource(resId, value);
        final BitmapFactory.Options options = new BitmapFactory.Options();
        options.inJustDecodeBounds = true;
        // options.inTargetDensity = value.density;
        BitmapFactory.decodeResource(res, resId, options);

        // Calculate inSampleSize
        calculateInSampleSize(options, reqWidth, reqHeight);
        // Decode bitmap with inSampleSize set
        options.inJustDecodeBounds = false;
        Bitmap bitmap = BitmapFactory.decodeResource(res, resId, options);
        if (reqWidth > 0 && reqHeight > 0) {
            bitmap = scale(bitmap, reqWidth, reqHeight);
        }
        return bitmap;
    }

    public static Bitmap alpha(Bitmap bitmap, int alpha) {
        if (bitmap == null)
            return null;
        int[] argb = new int[bitmap.getWidth() * bitmap.getHeight()];
        bitmap.getPixels(argb, 0, bitmap.getWidth(), 0, 0, bitmap.getWidth(), bitmap.getHeight());// 获得图片的ARGB值
        alpha = alpha * 255 / 100;
        for (int i = 0; i < argb.length; i++) {
            argb[i] = (alpha << 24) | (argb[i] & 0x00FFFFFF);
        }
        Bitmap ret = Bitmap.createBitmap(argb, bitmap.getWidth(), bitmap.getHeight(),
                Config.ARGB_8888);
        bitmap.recycle();
        return ret;
    }

    public static Bitmap scale(Bitmap bitmap, int width, int height) {
        if (bitmap == null)
            return null;
        int o_width = bitmap.getWidth();
        int o_height = bitmap.getHeight();
        Matrix matrix = new Matrix();
        matrix.postScale((float) width / (float) o_width, (float) height / (float) o_height); // 长和宽放大缩小的比例
        Bitmap resizeBmp = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(),
                matrix, true);
        return resizeBmp;
    }

    public static int calculateInSampleSize(BitmapFactory.Options options, int reqWidth,
                                            int reqHeight) {
        // Raw height and width of image
        final int height = options.outHeight;
        final int width = options.outWidth;
        int inSampleSize = 1;

        if (reqWidth > 0 && reqHeight > 0 && (height > reqHeight || width > reqWidth)) {
            if (width > height) {
                inSampleSize = Math.round((float) height / (float) reqHeight);
            } else {
                inSampleSize = Math.round((float) width / (float) reqWidth);
            }
        }
        return inSampleSize;
    }

    public static Bitmap decodeSampledBitmapFromFile(String path, int reqWidth, int reqHeight) {

        // First decode with inJustDecodeBounds=true to check dimensions
        final BitmapFactory.Options options = new BitmapFactory.Options();
        options.inJustDecodeBounds = true;
        BitmapFactory.decodeFile(path, options);

        // Calculate inSampleSize
        options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);

        // Decode bitmap with inSampleSize set
        options.inJustDecodeBounds = false;
        return BitmapFactory.decodeFile(path, options);
    }

    public static Bitmap changeBitmapBrightness(Bitmap bmp, float contrast, float brightness) {
        ColorMatrix cm = new ColorMatrix(new float[]
                {
                        contrast, 0, 0, 0, brightness,
                        0, contrast, 0, 0, brightness,
                        0, 0, contrast, 0, brightness,
                        0, 0, 0, 1, 0
                });
        Bitmap ret = Bitmap.createBitmap(bmp.getWidth(), bmp.getHeight(), bmp.getConfig());

        Canvas canvas = new Canvas(ret);

        Paint paint = new Paint();
        paint.setColorFilter(new ColorMatrixColorFilter(cm));
        canvas.drawBitmap(bmp, 0, 0, paint);

        return ret;
    }

    public static Bitmap gradient(Bitmap bitmap, int fromX, int fromY, int toX, int toY) {
        // 图片的宽度
        int width = bitmap.getWidth();
        // 图片的高度
        int height = bitmap.getHeight();

        // 创建标准的Bitmap对象，宽和原图一致，高是原图的1.5倍。 可以理解为这张图将会在屏幕上显示 是原图和倒影的合体
        Bitmap bitmapWithReflection = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
        // 构造函数传入Bitmap对象，为了在图片上画图
        Canvas canvas = new Canvas(bitmapWithReflection);
        // 画原始图片
        canvas.drawBitmap(bitmap, 0, 0, null);
        // 实现倒影渐变效果
        Paint paint = new Paint();
        LinearGradient shader = new LinearGradient(
                fromX, fromY, toX, toY, 0xffffffff, 0x30ffffff, Shader.TileMode.CLAMP);
        paint.setShader(shader);

        // Set the Transfer mode to be porter duff and destination in
        // 覆盖效果
        paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_IN));
        // Draw a rectangle using the paint with our linear gradient
        canvas.drawRect(0, 0, width, bitmapWithReflection.getHeight(), paint);

        return bitmapWithReflection;
    }
    public static Bitmap getRoundedCornerBitmap(Bitmap bitmap, float roundPx) {

        if (bitmap == null)
            return null;

        Bitmap output = Bitmap.createBitmap(bitmap.getWidth(),
                bitmap.getHeight(), Bitmap.Config.ARGB_8888);
        Canvas roundCanvas = new Canvas(output);
        roundCanvas.setDrawFilter(new PaintFlagsDrawFilter(0, Paint.ANTI_ALIAS_FLAG | Paint.FILTER_BITMAP_FLAG));
        roundCanvas.setBitmap(output);
        int color = 0xff424242;
        Paint paint = new Paint();
        Rect rect = new Rect(0, 0,
                bitmap.getWidth(), bitmap.getHeight());
        RectF rectF = new RectF(rect);
        paint.setFlags(Paint.ANTI_ALIAS_FLAG);
        paint.setAntiAlias(true);

        roundCanvas.drawARGB(0, 0, 0, 0);
        paint.setColor(color);
        roundCanvas.drawRoundRect(rectF, roundPx, roundPx, paint);
        paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));

        roundCanvas.drawBitmap(bitmap, rect, rect, paint);
        return output;
    }


}
